import 'dart:async';
import 'dart:convert';

import 'package:flutter/services.dart';
import 'package:flutter_bluetooth/BluetoothMsg.dart';

typedef void ReceiveBroadcast(BluetoothMsg btMsg);

class FlutterBluetooth {
  static const MethodChannel _channel =
      const MethodChannel('plugin.bgi.flutterbluetooth');
  static const EventChannel _eventChannel =
      const EventChannel('plugin.bgi.flutterbluetooth_scan_bluetooth');
  static StreamSubscription _streamSubscription;

  static ReceiveBroadcast receiveBtState,
      receiveBtScanState,
      receiveBtConnectState,
      receiveBtFind,
      receiveBtReadMsg;

  //使用前先初始化
  static void initReceiver({
    ReceiveBroadcast receiveBtState,
    ReceiveBroadcast receiveBtScanState,
    ReceiveBroadcast receiveBtConnectState,
    ReceiveBroadcast receiveBtFind,
    ReceiveBroadcast receiveBtReadMsg,
  }) {
    FlutterBluetooth.receiveBtState = receiveBtState;
    FlutterBluetooth.receiveBtScanState = receiveBtScanState;
    FlutterBluetooth.receiveBtConnectState = receiveBtConnectState;
    FlutterBluetooth.receiveBtFind = receiveBtFind;
    FlutterBluetooth.receiveBtReadMsg = receiveBtReadMsg;
    if(_streamSubscription == null){
      _streamSubscription = _eventChannel.receiveBroadcastStream().listen((msg) {
        Map map = json.decode(msg);
        BluetoothMsg btMsg = BluetoothMsg.fromJson(map);
        switch (btMsg.pushCode) {
          case BluetoothMsg.PUSHCODE_BLUETOOTH_STATE:
            if (FlutterBluetooth.receiveBtState != null)
              FlutterBluetooth.receiveBtState(btMsg);
            break;
          case BluetoothMsg.PUSHCODE_SCAN_STATE:
            if (FlutterBluetooth.receiveBtScanState != null)
              FlutterBluetooth.receiveBtScanState(btMsg);
            break;
          case BluetoothMsg.PUSHCODE_BLUETOOTH_CONNECTED_STATE:
            if (FlutterBluetooth.receiveBtConnectState != null)
              FlutterBluetooth.receiveBtConnectState(btMsg);
            break;
          case BluetoothMsg.PUSHCODE_FIND_BLUETOOTH:
            if (FlutterBluetooth.receiveBtFind != null)
              FlutterBluetooth.receiveBtFind(btMsg);
            break;
          case BluetoothMsg.PUSHCODE_READ_MSG:
            if (FlutterBluetooth.receiveBtReadMsg != null)
              FlutterBluetooth.receiveBtReadMsg(btMsg);
            break;
        }
      });
    }
  }

  static Future<int> get blueState async {
    final int state = await _channel.invokeMethod('blueState');
    return state;
  }

  static startDiscovery() async {
    await _channel.invokeMethod('startDiscovery');
  }

  static connect(BluetoothMsg btMsg,String alertDialogs,
      {String uuid = "00001101-0000-1000-8000-00805F9B34FB"}) async {
    await _channel.invokeMethod('connect', {
      "address": btMsg.address,
      "alertDialogs": alertDialogs,
      "uuid": uuid,
    });
  }

  static bleConnect(BluetoothMsg btMsg, String serviceUuid,
      String characteristicUuid, String descriptorUuid) async {
    await _channel.invokeMethod('bleConnect', {
      "address": btMsg.address,
      "serviceUuid": serviceUuid,
      "characteristicUuid": characteristicUuid,
      "descriptorUuid": descriptorUuid,
    });
  }

  static openBluetooth() async {
    await _channel.invokeMethod('openBluetooth');
  }

  static cancelDiscovery() async {
    await _channel.invokeMethod('cancelDiscovery');
  }

  static readyRead() async {
    await _channel.invokeMethod('readyRead');
  }

  static send(String msg) async {
    await _channel.invokeMethod('send', {
      "msg": msg,
    });
  }

  static disconnect() async {
    await _channel.invokeMethod('disconnect');
  }

  static disconnectBle() async {
    await _channel.invokeMethod('disconnectBle');
  }

  static disconnectWithPushState() async {
    await _channel.invokeMethod('disconnectWithPushState');
  }

  static disconnectBleWithPushState() async {
    await _channel.invokeMethod('disconnectBleWithPushState');
  }

  static dispose() {
    _channel.invokeMethod('cancelDiscovery');
    FlutterBluetooth.receiveBtState = null;
    FlutterBluetooth.receiveBtScanState = null;
    FlutterBluetooth.receiveBtConnectState = null;
    FlutterBluetooth.receiveBtFind = null;
    FlutterBluetooth.receiveBtReadMsg = null;
    _channel.invokeMethod('disconnectBle');
    _channel.invokeMethod('disconnect');
  }
}
